package com.ruoyi.business.communication.domain;

import java.io.Serializable;

/**
 * 槽设置信息对象
 * <p>
 * 结构：16位无符号整型
 * - 最高4位：指令种类 (0-5)
 * - 中间4位：点位/缸号 (1-6, 0=预留)
 * - 最低8位：指令/数据 (根据指令种类含义不同)
 * 
 * 指令种类定义：
 * 0: 动作 (数据: 0=打壳, 1=下料)
 * 1: 打壳时间 (数据: 25=2.5秒)
 * 2: 换极阶段1 (数据: 10=10分钟)
 * 3: 换极阶段2 (数据: 10=10分钟)
 * 4: 自动换极号 (数据: 1=A1 到 12=A12, 17=B1到28=B12)
 * 5: 预留
 */
public class SlotSetting implements Serializable {

    private static final long serialVersionUID = 1L;

    /** 指令种类枚举 */
    public enum CommandType {
        ACTION(0, "动作"),
        STRIKE_TIME(1, "打壳时间"),
        POLE_CHANGE_STAGE1(2, "换极阶段1"),
        POLE_CHANGE_STAGE2(3, "换极阶段2"),
        AUTO_POLE_NUMBER(4, "自动换极号"),
        RESERVED(5, "预留");

        private final int code;
        private final String description;

        CommandType(int code, String description) {
            this.code = code;
            this.description = description;
        }

        public int getCode() { return code; }
        public String getDescription() { return description; }

        public static CommandType fromCode(int code) {
            for (CommandType type : values()) {
                if (type.code == code) return type;
            }
            throw new IllegalArgumentException("未知指令种类代码: " + code);
        }
    }

    /** 点位/缸号枚举 */
    public enum PositionNumber {
        RESERVED(0, "预留"),
        POSITION_1(1, "点位1"),
        POSITION_2(2, "点位2"),
        POSITION_3(3, "点位3"),
        POSITION_4(4, "点位4"),
        POSITION_5(5, "点位5"),
        POSITION_6(6, "点位6");

        private final int code;
        private final String description;

        PositionNumber(int code, String description) {
            this.code = code;
            this.description = description;
        }

        public int getCode() { return code; }
        public String getDescription() { return description; }

        public static PositionNumber fromCode(int code) {
            for (PositionNumber pos : values()) {
                if (pos.code == code) return pos;
            }
            throw new IllegalArgumentException("未知点位代码: " + code);
        }
    }

    /** 动作类型枚举 */
    public enum ActionType {
        STRIKE(0, "打壳"),
        DISCHARGE(1, "下料");

        private final int code;
        private final String description;

        ActionType(int code, String description) {
            this.code = code;
            this.description = description;
        }

        public int getCode() { return code; }
        public String getDescription() { return description; }

        public static ActionType fromCode(int code) {
            for (ActionType action : values()) {
                if (action.code == code) return action;
            }
            throw new IllegalArgumentException("未知动作代码: " + code);
        }
    }

    // 字段
    private Integer businessSlotNo;
    private CommandType commandType;
    private PositionNumber positionNumber;
    private Integer data; // 8位数据

    public SlotSetting(Integer businessSlotNo) {
        this.businessSlotNo = businessSlotNo;
    }

    private SlotSetting(Integer businessSlotNo,
                        CommandType commandType, 
                        PositionNumber positionNumber, 
                        Integer data) {
        this.businessSlotNo = businessSlotNo;
        this.commandType = commandType;
        this.positionNumber = positionNumber;
        this.data = data;
    }

    /**
     * 从16位无符号整型构建对象
     */
    public static SlotSetting fromUint16(Integer businessSlotNo,int value) {
        // 提取最高4位 (位12-15)
        int commandCode = (value >> 12) & 0xF;
        // 提取中间4位 (位8-11)
        int positionCode = (value >> 8) & 0xF;
        // 提取最低8位 (位0-7)
        int dataValue = value & 0xFF;

        return new SlotSetting(
            businessSlotNo,
            CommandType.fromCode(commandCode),
            PositionNumber.fromCode(positionCode),
            dataValue
        );
    }

    /**
     * 转换为16位无符号整型
     */
    public int toUint16() {
        int commandBits = (commandType.getCode() & 0xF) << 12;
        int positionBits = (positionNumber.getCode() & 0xF) << 8;
        int dataBits = (data != null ? data : 0) & 0xFF;
        
        return commandBits | positionBits | dataBits;
    }

    /**
     * 获取动作类型（仅当指令种类为动作时有效）
     */
    public ActionType getActionType() {
        if (commandType != CommandType.ACTION || data == null) {
            return null;
        }
        return ActionType.fromCode(data);
    }

    /**
     * 设置动作类型（仅当指令种类为动作时有效）
     */
    public void setActionType(ActionType actionType) {
        if (commandType == CommandType.ACTION && actionType != null) {
            this.data = actionType.getCode();
        }
    }

    /**
     * 获取打壳时间（秒，仅当指令种类为打壳时间时有效）
     */
    public Double getStrikeTimeSeconds() {
        if (commandType != CommandType.STRIKE_TIME || data == null) {
            return null;
        }
        return data / 10.0; // 25 -> 2.5秒
    }

    /**
     * 设置打壳时间（秒，仅当指令种类为打壳时间时有效）
     */
    public void setStrikeTimeSeconds(Double seconds) {
        if (commandType == CommandType.STRIKE_TIME && seconds != null) {
            this.data = (int) (seconds * 10); // 2.5秒 -> 25
        }
    }

    /**
     * 获取换极时间（分钟，仅当指令种类为换极阶段时有效）
     */
    public Integer getPoleChangeTimeMinutes() {
        if ((commandType != CommandType.POLE_CHANGE_STAGE1 
        && commandType != CommandType.POLE_CHANGE_STAGE2) || data == null) {
            return null;
        }
        return data; // 直接返回分钟数
    }

    /**
     * 设置换极时间（分钟，仅当指令种类为换极阶段时有效）
     */
    public void setPoleChangeTimeMinutes(Integer minutes) {
        if ((commandType == CommandType.POLE_CHANGE_STAGE1 
            || commandType == CommandType.POLE_CHANGE_STAGE2) && minutes != null) {
            this.data = minutes;
        }
    }

    /**
     * 获取自动换极号描述（仅当指令种类为自动换极号时有效）
     */
    public String getAutoPoleNumberDescription() {
        if (commandType != CommandType.AUTO_POLE_NUMBER || data == null) {
            return null;
        }
        
        if (data >= 1 && data <= 12) {
            return "A" + data;
        } else if (data >= 17 && data <= 28) {
            return "B" + (data - 16);
        } else {
            return "未知换极号: " + data;
        }
    }

    /**
     * 设置自动换极号（仅当指令种类为自动换极号时有效）
     * @param poleNumber 换极号，如 "A1"- "A12", "B1"-"B12"
     */
    public void setAutoPoleNumber(String poleNumber) {
        if (commandType == CommandType.AUTO_POLE_NUMBER && poleNumber != null) {
            if (poleNumber.startsWith("A")) {
                int num = Integer.parseInt(poleNumber.substring(1));
                if (num >= 1 && num <= 12) {
                    this.data = num;
                }
            } else if (poleNumber.startsWith("B")) {
                int num = Integer.parseInt(poleNumber.substring(1));
                if (num >= 1 && num <= 12) {
                    this.data = num + 16; // B1=17, B12=28
                }
            }
        }
    }

    /**
     * 获取业务槽号
     * @return 业务槽号
     */
    public Integer getBusinessSlotNo() {
        return businessSlotNo;
    }

    /**
     * 设置业务槽号
     * @param businessSlotNo 业务槽号
     */
    public void setBusinessSlotNo(Integer businessSlotNo) {
        this.businessSlotNo = businessSlotNo;
    }
    // Getters and Setters
    public CommandType getCommandType() { return commandType; }
    public void setCommandType(CommandType commandType) { this.commandType = commandType; }
    
    public PositionNumber getPositionNumber() { return positionNumber; }
    public void setPositionNumber(PositionNumber positionNumber) { this.positionNumber = positionNumber; }
    
    public Integer getData() { return data; }
    public void setData(Integer data) { this.data = data; }

    @Override
    public String toString() {
        return String.format("SlotSetting{commandType=%s, positionNumber=%s, data=%d, uint16=0x%04X}", 
            commandType, positionNumber, data, toUint16());
    }
}
